package top.healthylife.gateway.platform.eye.api.api.aggregation;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import top.healthylife.gateway.core.service.ParentFace;
import top.healthylife.gateway.dto.annotation.ApiServiceExplain;
import top.healthylife.gateway.platform.eye.api.api.sifafengxian.EyeDishonestApi;
import top.healthylife.gateway.platform.eye.api.api.sifafengxian.EyeEndCaseApi;
import top.healthylife.gateway.platform.eye.api.api.sifafengxian.EyeLawSuitApi;
import top.healthylife.gateway.platform.eye.api.api.sifafengxian.EyeZhixinginfoApi;
import top.healthylife.gateway.platform.eye.dto.aggregation.req.EyeReqAggregationDataDto;
import top.healthylife.gateway.platform.eye.dto.aggregation.res.EyeResAggregationDataDto;
import top.healthylife.gateway.platform.eye.dto.sifafengxian.EyeReqDishonestDto.res.EyeResDishonestDto;
import top.healthylife.gateway.platform.eye.dto.sifafengxian.EyeReqDishonestDto.res.EyeResDishonestItem;
import top.healthylife.gateway.platform.eye.dto.sifafengxian.EyeReqEndCaseDto.res.EyeResEndCaseDto;
import top.healthylife.gateway.platform.eye.dto.sifafengxian.EyeReqLawSuitDto.res.EyeResLawSuitDto;
import top.healthylife.gateway.platform.eye.dto.sifafengxian.EyeReqLawSuitDto.res.EyeResLawSuitItem;
import top.healthylife.gateway.platform.eye.dto.sifafengxian.EyeReqZhixinginfoDto.res.EyeResZhixinginfoDto;
import top.healthylife.gateway.platform.eye.dto.sifafengxian.EyeReqZhixinginfoDto.res.EyeResZhixinginfoItem;

import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * @author: GenUtil
 * @date: 2020-12-15 19:07:12
 */
@Slf4j
@Service
@AllArgsConstructor
@ApiServiceExplain(price = 500, docUrl = "", apiName = "数据聚合接口", info = "数据聚合来源于 法律诉讼[842],失信人[843],被执行人[839],终本案件[1013],等接口")
public class EyeAggregationDataApi implements ParentFace<EyeReqAggregationDataDto, EyeResAggregationDataDto> {
    /**
     * 法律诉讼[842]
     */
    EyeLawSuitApi eyeLawSuitApi;

    /**
     * 失信人[843]
     */
    EyeDishonestApi eyeDishonestApi;

    /**
     * 被执行人[839]
     */
    EyeZhixinginfoApi eyeZhixinginfoApi;

    /**
     * 终本案件[1013]
     */
    EyeEndCaseApi eyeEndCaseApi;

    /**
     * 执行这个服务接口
     * 如果成功，返回成功结果，如果接口错误，直接抛异常即可
     *
     * @param eyeDto 请求参数
     * @return 查询的真实结果，如果是失败，则直接返回异常即可
     */
    @Override
    public EyeResAggregationDataDto execute(EyeReqAggregationDataDto eyeDto) {
        String keyword = eyeDto.getKeyword();
        //法律诉讼[842]
        EyeResLawSuitDto eyeResLawSuitDto = eyeLawSuitApi.getAllRecord(eyeDto);
        //失信人[843]
        EyeResDishonestDto eyeResDishonestDto = eyeDishonestApi.getAllRecord(eyeDto);
        //被执行人[839]
        EyeResZhixinginfoDto eyeResZhixinginfoDto = eyeZhixinginfoApi.getAllRecord(eyeDto);
        //终本案件[1013]
        EyeResEndCaseDto eyeResEndCaseDto = eyeEndCaseApi.getAllRecord(eyeDto);
        //fixme 修正统计口径
        EyeResAggregationDataDto eyeResAggregationDataDto = new EyeResAggregationDataDto();
        eyeResAggregationDataDto.setTimesOfBeMarkedAsDishonestExecutorOverLast1080Days(getTimesOfBeMarkedAsDishonestExecutorOverLastNDays(eyeResDishonestDto, 1080))
                .setTimesOfBeMarkedAsPersonToBeExecutedOverLast360Days(getTimesOfBeMarkedAsPersonToBeExecutedOverLastNDays(eyeResZhixinginfoDto, 360))
                .setTimesOfCasesInHistory(getTimesOfCasesInHistory(eyeResEndCaseDto))
                .setTimesOfCauseOfActionDisputesOverLast90Days(getTimesOfCauseOfActionDisputesOverLastNDays(eyeResLawSuitDto, 90, keyword))
                .setTimesOfCauseOfActionDisputesOverLast360Days(getTimesOfCauseOfActionDisputesOverLastNDays(eyeResLawSuitDto, 360, keyword));
        return eyeResAggregationDataDto;
    }

    /**
     * 近n天作为被告涉及“借贷”、“借款”案由纠纷的次数
     *
     * @param eyeResLawSuitDto 法律诉讼dto
     * @param n                近n天
     * @return 近n天作为被告涉及“借贷”、“借款”案由纠纷的次数
     */
    public Integer getTimesOfCauseOfActionDisputesOverLastNDays(EyeResLawSuitDto eyeResLawSuitDto, int n, String currentCompany) {
        List<EyeResLawSuitItem> items = eyeResLawSuitDto.getItems();
        DateTime now = DateTime.now();
        DateTime dateTime = now.offsetNew(DateField.DAY_OF_YEAR, -n);
        //judgetime在近n天内 且 defendants包含当前企业名称
        Predicate<EyeResLawSuitItem> predicate = e -> DateUtil.parseDate(e.getJudgetime()).isIn(dateTime, now) &&
                ObjectUtil.isNotEmpty(e.getDefendants()) && e.getDefendants().contains(currentCompany) &&
                e.getCasereason().contains("借贷") || e.getCasereason().contains("借款");
        List<EyeResLawSuitItem> collect = items.stream().filter(predicate).collect(Collectors.toList());
        return collect.size();
    }

    /**
     * 近n天作为被执行人的次数
     *
     * @param eyeResZhixinginfoDto 被执行人 dto
     * @param n                    近n天
     * @return 近n天作为被执行人的次数
     */
    public Integer getTimesOfBeMarkedAsPersonToBeExecutedOverLastNDays(EyeResZhixinginfoDto eyeResZhixinginfoDto, int n) {
        List<EyeResZhixinginfoItem> items = eyeResZhixinginfoDto.getItems();
        DateTime now = DateTime.now();
        DateTime dateTime = now.offsetNew(DateField.DAY_OF_YEAR, -n);
        //caseCreateTime在360天内  且 caseCode非空的次数
        Predicate<EyeResZhixinginfoItem> predicate = e -> DateTime.of(e.getCaseCreateTime()).isIn(dateTime, now) &&
                ObjectUtil.isNotNull(e.getCaseCode());

        return (int) items.stream().filter(predicate).count();
    }

    /**
     * 历史终本案件的次数
     *
     * @param eyeResEndCaseDto 终本案件
     * @return 历史终本案件的次数
     */
    public Integer getTimesOfCasesInHistory(EyeResEndCaseDto eyeResEndCaseDto) {
        return (int) eyeResEndCaseDto.getItems().stream().filter(e -> ObjectUtil.isNotNull(e.getCaseCode())).count();
    }

    /**
     * 近n天作为失信被执行人的次数
     *
     * @param eyeResDishonestDto 失信人
     * @return 历史终本案件的次数
     */
    public Integer getTimesOfBeMarkedAsDishonestExecutorOverLastNDays(EyeResDishonestDto eyeResDishonestDto, int n) {
        List<EyeResDishonestItem> items = eyeResDishonestDto.getItems();
        DateTime now = DateTime.now();
        DateTime dateTime = now.offsetNew(DateField.DAY_OF_YEAR, -n);
        //regdate在1080天内  且 caseCode非空的次数
        Predicate<EyeResDishonestItem> predicate = e -> DateTime.of(e.getRegdate()).isIn(dateTime, now) &&
                ObjectUtil.isNotNull(e.getCasecode());

        return (int) items.stream().filter(predicate).count();
    }
}
